// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// FREE SOURCE CODE
// http://www.magic-software.com/License/free.pdf

#ifndef MGCMINIMIZEND_H
#define MGCMINIMIZEND_H

#include "MgcMinimize1D.h"


class MgcMinimizeND
{
public:
    typedef MgcReal (*Function)(const MgcReal*,void*);

    MgcMinimizeND (int iDimensions, Function oF, unsigned int uiMaxLevel,
        unsigned int uiMaxBracket, unsigned int uiMaxIterations,
        void* pvUserData = 0);

    ~MgcMinimizeND ();

    unsigned int& MaxLevel ();
    unsigned int& MaxBracket ();
    void*& UserData ();

    // find minimum on Cartesian-product domain
    void GetMinimum (const MgcReal* afT0, const MgcReal* afT1,
        const MgcReal* afTInitial, MgcReal* afTMin, MgcReal& rfFMin);

protected:
    int m_iDimensions;
    Function m_oF;
    unsigned int m_uiMaxIterations;
    void* m_pvUserData;
    MgcMinimize1D m_kMinimizer;
    MgcReal* m_afDirectionStorage;
    MgcReal** m_aafDirection;
    MgcReal* m_afDConj;
    MgcReal* m_afDCurr;
    MgcReal* m_afTSave;
    MgcReal* m_afTCurr;
    MgcReal m_fFCurr;
    MgcReal* m_afLineArg;

    void ComputeDomain (const MgcReal* afT0, const MgcReal* afT1,
        MgcReal& rfL0, MgcReal& rfL1);

    static MgcReal LineFunction (MgcReal fT, void* pvUserData);
};

//----------------------------------------------------------------------------
inline unsigned int& MgcMinimizeND::MaxLevel ()
{
    return m_kMinimizer.MaxLevel();
}
//----------------------------------------------------------------------------
inline unsigned int& MgcMinimizeND::MaxBracket ()
{
    return m_kMinimizer.MaxBracket();
}
//----------------------------------------------------------------------------
inline void*& MgcMinimizeND::UserData ()
{
    return m_pvUserData;
}
//----------------------------------------------------------------------------

#endif
